#include "socketclient.h"
#include "Log.h"

SocketClinet::SocketClinet(std::string ip_, int port_)
{
    char buf[128]={0};
    sprintf(buf,"%s:%d",ip_.c_str(),port_);
    addr_ = acl::string(buf,strlen(buf));
}

SocketClinet::~SocketClinet()
{
}

bool SocketClinet::connect()
{
    if (client.open(addr_, 0, 1) == false)
	{
		CLogger::createInstance()->Log(MsgWarn
            ,"open %s error:%s"
            , addr_.c_str()
            ,acl::last_serror());
		return false;
	}else{
        client.set_tcp_non_blocking(true);
        // client.set_tcp_nodelay(true);
        // client.set_rw_timeout(1);
        #ifdef WIN32
		SOCKET sock_fd = client.sock_handle();
		int nNetTimeout = 10; 
		setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&nNetTimeout, sizeof(int));
		setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&nNetTimeout, sizeof(int));
		#endif
        CLogger::createInstance()->Log(MsgInfo
            ,"open %s success", addr_.c_str());
    }
    return true;
}

bool SocketClinet::isConnect()
{
    return client.alive();
}

bool SocketClinet::disConnect()
{
    if(client.close()==false)
    {
        CLogger::createInstance()->Log(MsgWarn
            ,"close %s error[%d,%s]"
            , addr_.c_str()
            , acl_last_error()
            , acl::last_serror());
        return false;
    }
    return true;
}

int SocketClinet::Read(RDClient &bufs)
{
	try {
        char buf[256] = { 0 };
        int len = client.read(buf, 256,false);
        if (len<0)
        {
            int lerror = acl_last_error();
            if(10060!=lerror
                &&110!=lerror
                &&0!=lerror)
            {
                disConnect();
                CLogger::createInstance()->Log(MsgWarn,
                    "[%s] Read Datas Failed: [%d,%s]! [%s %s %d]"
                    , addr_.c_str(),lerror,acl::last_serror()
                    , __FILE__, __FUNCTION__, __LINE__);
            }
            return 0;
        }
        if (len > 0) 
        {
            // printf("SocketClinet read:\n");
            // for (int j = 0; j < len; j++) {
            //     printf("%02X", static_cast<unsigned char>(buf[j]));
            // }
            // printf("\n");
            bufs.add((unsigned char*)buf, len);
            return bufs.len;
        }
        return 0;
	}
	catch (...) {
		disConnect();
        CLogger::createInstance()->Log(MsgError,
                "[%s] Read Datas Error: %s! [%s %s %d]"
                , addr_.c_str(),acl::last_serror()
                , __FILE__, __FUNCTION__, __LINE__);
        return -1;
	}
}

int SocketClinet::Read(char* buf, unsigned int size)
{
    try{
        char buf_[256] = { 0 };
        int len = client.read(buf_, 256,false);
        if (len<0)
        {
            int lerror = acl_last_error();
            if(10060!=lerror
                &&110!=lerror
                &&0!=lerror)
            {
                disConnect();
                CLogger::createInstance()->Log(MsgWarn,
                    "[%s] Read Data Failed: [%d,%s]! [%s %s %d]"
                    , addr_.c_str(),lerror,acl::last_serror()
                    , __FILE__, __FUNCTION__, __LINE__);
            }
            return 0;
        }
        if(len>static_cast<int>(size))
        {
            strncpy(buf,buf_,size);
        }else{
            strncpy(buf,buf_,len);
        }
        return static_cast<int>(strlen(buf));
    }catch(...){
        disConnect();
        CLogger::createInstance()->Log(MsgError,
			"[%s] Read Data Error: %s! [%s %s %d]"
            , addr_.c_str(),acl::last_serror()
			, __FILE__, __FUNCTION__, __LINE__);
        return -1;
    }
}

int SocketClinet::Write(const char* buf, unsigned int size)
{
    try{
        int ret = client.write(buf, size);
        if ( ret<0)
        {
            disConnect();
            CLogger::createInstance()->Log(MsgWarn,
			"[%s] write Data[%d,%s] Failed: [%d,%s]! [%s %s %d]"
            , addr_.c_str(),size,buf,acl_last_error(),acl::last_serror()
			, __FILE__, __FUNCTION__, __LINE__);
        }
        return ret;
    }catch(...){
        disConnect();
        CLogger::createInstance()->Log(MsgError,
			"[%s] Read Data Error: %s! [%s %s %d]"
            , addr_.c_str(),acl::last_serror()
			, __FILE__, __FUNCTION__, __LINE__);
        return -2;
    }
}